<template>
  <Category :disable="!isShowList" />
  <el-card shadow="always" :body-style="{ padding: '20px' }" :style="{ marginTop: '30px' }">
    <template #header v-if="isShowList">
      <el-button type="primary" size="default" @click="addAttr" :icon="Plus" :disabled="!category3Id">新增属性</el-button>
    </template>
    <el-table border stripe :data="attrList" v-if="isShowList">
      <el-table-column label="序号" type="index" width="80" />
      <el-table-column label="属性名称" width="150" prop="attrName"></el-table-column>
      <el-table-column label="属性值名称列表" prop="attrValueList">
        <template v-slot="{ row }">
          <el-tag type="danger" size="default" effect="dark" v-for="item in row.attrValueList" :key="item.id">{{
              item.valueName
          }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="操作" width="150">
        <template v-slot="{ row }">
          <el-button type="warning" size="default" @click="editAttr(row)" :icon="Edit"></el-button>
          <el-popconfirm title="确定要删除该属性吗?" @confirm="deleteAttr(row)">
            <template #reference>
              <el-button type="danger" size="default" :icon="Delete"></el-button>
            </template>
          </el-popconfirm>
        </template>
      </el-table-column>
    </el-table>
    <div v-else>
      <el-form label-width="80px" :inline="true" style="margin-left: -25px">
        <el-form-item label="属性名">
          <el-input placeholder="输入属性名" v-model="newAttrData.attrName"></el-input>
        </el-form-item>
      </el-form>
      <div>
        <el-button type="primary" @click="addAttrValue" :disabled="!newAttrData.attrName">添加属性值</el-button>
        <el-button type="default" @click="cancel">取消</el-button>
      </div>
      <el-table :data="newAttrData.attrValueList" border stripe :style="{ marginTop: '30px' }">
        <el-table-column type="index" width="50" label="序号" />
        <el-table-column label="属性值名称" prop="valueName">
          <template v-slot="{ row, $index }">
            <el-input v-model="row.valueName" placeholder="请输入新增的属性值名称" size="default" v-if="row.isEdit"
              @blur="changToLook(row, $index)" @focus="saveOldValue(row)" ref="editEle"></el-input>
            <span v-else @click="changToEdit(row)">{{ row.valueName }}</span>
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template v-slot="{ $index }">
            <el-popconfirm title="确定要删除该属性吗?" @confirm="deleteAttrValue($index)">
              <template #reference>
                <el-button type="danger" size="default" icon="ele-Delete"></el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
      <div style="margin-top: 30px">
        <el-button type="primary" @click="saveAttr"
          :disabled="newAttrData.attrValueList.length <= 0 || !newAttrData.attrName">保存</el-button>
        <el-button type="default" @click="cancel">取消</el-button>
      </div>
    </div>
  </el-card>
</template>

<script lang="ts">
import { defineComponent } from "vue";


export default defineComponent({
  name: "Attr",
});
</script>

<script setup lang="ts">
import { Plus, Edit, Delete } from "@element-plus/icons-vue";
import { watch, ref, nextTick } from "vue";
import useAttrStore from "@/stores/attr";
import { storeToRefs } from "pinia";
import type { attrListType, attrListItemType, attrValueListType } from "@/api/attr";
import { requestAttrList, requestUpdateOrAddAttr, requestDeleteAttr } from "@/api/attr";
import cloneDeep from "lodash/cloneDeep";
import { ElMessage } from "element-plus";

const attrStore = useAttrStore();
const { category3Id, category2Id, category1Id } = storeToRefs(attrStore);

//存放三级分类得到的属性列表
const attrList = ref<attrListType>([]);
//监听第三级分类的改变,然后请求属性列表
// 封装请求属性列表函数
const getAttrList = async () => {
  const result = await requestAttrList(
    category1Id.value as number,
    category2Id.value as number,
    category3Id.value as number
  );

  attrList.value = result;
}
watch(
  category3Id,
  (newValue) => {
    if (!newValue) return;
    getAttrList()
  },
  { immediate: true }
);

// 添加平台属性
const newAttrData = ref<attrListItemType>({
  attrName: '',
  categoryId: category3Id.value as number,
  categoryLevel: 3,
  attrValueList: [],
})

// 创建一个响应数据用来切换新增页和属性列表页
const isShowList = ref(true)

// 添加属性函数
const addAttr = () => {
  // 切换到新增页
  isShowList.value = false
  // 每次点击添加属性时先清空上一次残留的数据
  newAttrData.value = {
    attrName: '',
    categoryId: category3Id.value as number,
    categoryLevel: 3,
    attrValueList: [],
  }
}

// 取消函数
const cancel = () => {
  // 切换到属性列表页
  isShowList.value = true
}

// 添加属性值事件
const addAttrValue = () => {
  // 创建一个属性值数据
  const newAttrValue = ref({
    valueName: '',
    attrId: newAttrData.value.id,
    isEdit: true
  })
  // 将新属性值数据给到新属性的属性值列表的数组中
  newAttrData.value.attrValueList.push(newAttrValue.value)
  // 让当前表单自动获取焦点
  nextTick(() => {
    editEle.value.focus()
  })
}

// 属性列表中修改属性值
const editAttr = (row: attrListItemType) => {
  // 先跳到新增和修改页
  isShowList.value = false
  // 拿到深拷贝的数据
  const clonedeep = cloneDeep(row)
  // 遍历深拷贝数据,给里面的每一个对象添加一个isEdit属性值为false,来设定它为非编辑模式
  clonedeep.attrValueList.forEach(item => {
    item.isEdit = false
  })
  // 回填数据的时候,直接将上面添加了属性的数据给newAttrData即可
  newAttrData.value = clonedeep
}

// 创建一个数据用来保存编辑模式的input元素
const editEle = ref()

// 点击切换到编辑模式函数
const changToEdit = (row: attrValueListType) => {
  row.isEdit = true
  // 让当前表单自动获取焦点
  nextTick(() => {
    editEle.value.focus()
  })
}

let oldAttrValueName = ''
// 获取焦点的时候保存旧值
const saveOldValue = (row: attrValueListType) => {
  oldAttrValueName = row.valueName
}

// 点击切换到查看模式函数
const changToLook = (row: attrValueListType, $index: number) => {
  row.isEdit = false
  // 判断当前输入是否为空和旧值是否为空
  if (!row.valueName.trim()) {
    if (!oldAttrValueName) {
      // 都为空说明用户是在添加并且值为空,直接删除该行数据
      newAttrData.value.attrValueList.splice($index, 1)
    } else {
      // 有旧值将值还给用户即可
      row.valueName = oldAttrValueName
    }
  }

  // 判断用户输入的是否有重复,如果除去自己之外还有重复的
  let isRepeat = newAttrData.value.attrValueList.some(item => {
    if (item === row) {
      return;
    }
    return item.valueName === row.valueName
  })

  // 先判断是否有旧值, 如果有旧值就将旧值重新还给用户
  if (isRepeat) {
    if (oldAttrValueName) {
      row.valueName = oldAttrValueName;
    } else {
      // 如果没有则删除该行
      newAttrData.value.attrValueList.splice($index, 1);
    }
  }
  // 清空旧值
  oldAttrValueName = ''
}

// 确认删除属性的事件
const deleteAttrValue = ($index: number) => {
  newAttrData.value.attrValueList.splice($index, 1);
}

// 确认保存修改的属性的事件
const saveAttr = async () => {
  // 保存前先删除attrValueList里的isEdit属性
  newAttrData.value.attrValueList.forEach(item => {
    delete item.isEdit
  })
  // 先判断属性值是否为空
  if (newAttrData.value.attrValueList.length <= 0) {
    ElMessage.error("属性值不能为空")
    return;
  }
  try {
    // 发送请求
    await requestUpdateOrAddAttr(newAttrData.value)
    ElMessage.success("新增或修改成功")
    // 切回属性列表页
    isShowList.value = true
    // 重新请求属性列表
    getAttrList()
  } catch (e) {
    ElMessage.error("新增或修改失败")
  }
}

// 删除某条属性的请求
const deleteAttr = async (row: attrListItemType) => {
  try {
    await requestDeleteAttr(row.id as number)
    ElMessage.success("删除成功")
    // 重新请求属性列表
    getAttrList()
  } catch (e) {
    ElMessage.error("删除失败")
  }
}
</script>
